package android.FiltrosJava;

import java.awt.image.*;

public class SphereFilter extends TransformFilter{
	private float a = 0;
	private float b = 0;
	private float a2 = 0;
	private float b2 = 0;
	private float refractionIndex = 1.5f;

	private float HALF_PI = (float) (Math.PI/2.0f);
	private float icentreX;
	private float icentreY;

	public SphereFilter(float refaction){
		refractionIndex = Math.abs(refaction);				
	}
	
	public BufferedImage applyFilter( BufferedImage src) {
		int width = src.getWidth();
		int height = src.getHeight();
		icentreX = width/2.0f;
		icentreY = height/2.0f;
		a = Math.min(icentreX,icentreY);
		b = a;
		
		a2 = a*a;
		b2 = b*b;
		return super.applyFilter( src);
	}
	
	protected void transformInverse(int x, int y, float[] out) {
		float dx = x-icentreX;
		float dy = y-icentreY;
		float x2 = dx*dx;
		float y2 = dy*dy;
		if (y2 >= (b2 - (b2*x2)/a2)) {
			out[0] = x;
			out[1] = y;
		} else {
			float rRefraction = 1.0f / refractionIndex;

			float z = (float)Math.sqrt((1.0f - x2/a2 - y2/b2) * (a*b));
			float z2 = z*z;

			float xAngle = (float)Math.acos(dx / Math.sqrt(x2+z2));
			float angle1 = HALF_PI - xAngle;
			float angle2 = (float)Math.asin(Math.sin(angle1)*rRefraction);
			angle2 = HALF_PI - xAngle - angle2;
			out[0] = x - (float)Math.tan(angle2)*z;

			float yAngle = (float)Math.acos(dy / Math.sqrt(y2+z2));
			angle1 = HALF_PI - yAngle;
			angle2 = (float)Math.asin(Math.sin(angle1)*rRefraction);
			angle2 = HALF_PI - yAngle - angle2;
			out[1] = y - (float)Math.tan(angle2)*z;
		}
	}


}
